#include <iostream>
#include <sys/timeb.h>
#include <time.h>

#include "CServiceProxy.h"

#include "space/CMessage.h"
#include "space/CKeyValue.h"

//#ifndef INFINITE
//#define INFINITE
//#endif

using namespace std;

int getRandom()
{
	struct timeb itb;
	struct tm *lt;
	ftime(&itb);
	lt = localtime(&itb.time);
	srand(lt->tm_sec+itb.millitm);

	int random_port = rand();

	return random_port;
}

int main(int argc, char **argv)
{
	if(argc<2) {
		cout << "==============================================" << endl;
		cout << "For CGI Server : " << argv[0] << endl;
		cout << "For Stand-alone Server : " << argv[0] << " <port>" << endl;
		cout << "==============================================" << endl;
	}

#ifdef INFINITE
	for(long num=0;;num++) {
	cout << "============= " << num << " ============" << endl;
#endif

	CServiceProxy proxy;
	if(argc>1) proxy.connect("localhost", atoi(argv[1]));

	cout << "=========================================================" << endl;
	cout << "[test]Echo" << endl;
	cout << "=========================================================" << endl;
	CObjectArray *pobjs = new CObjectArray(3);
	//pobjs->grow(1);
	(*pobjs)[0] = new cube__CMessage();
	(*pobjs)[1] = new cube__CMessage();
	(*pobjs)[2] = new cube__CMessage();
	dynamic_cast<cube__CMessage *>((*pobjs)[0])->set("[echo1]woorung nara");
	dynamic_cast<cube__CMessage *>((*pobjs)[1])->set("[echo2]this is test");
	dynamic_cast<cube__CMessage *>((*pobjs)[2])->set("[echo3]oops from here");

	cube__CService echo_service;
	echo_service.service("sample.echo.service2");

	char random_instance[20];
	sprintf(random_instance, "random.instance.%d", getRandom());
	echo_service.instance(random_instance);

	int nothing;
	cout << "------------------ initialize --------------------" << endl;
	proxy.initialize(&echo_service, nothing);

	struct cube__invokeResponse res1;

	// invoke echo service
	if(proxy.invoke(&echo_service, pobjs, res1)!=SOAP_OK) {
		soap_print_fault(proxy.soap(), stderr);

		delete (*pobjs)[0];
		delete (*pobjs)[1];
		delete (*pobjs)[2];
		delete pobjs;

		return -1;
	}

	cout << "-------------- sample.echo.service2 -------------" << endl;
	cout << "response size = " << ((CObjectArray *)res1.out)->__size << endl;

	CObjectArray *robjs = dynamic_cast<CObjectArray *>(res1.out);

	for(int i=0;i<robjs->__size;i++) {
		cube__CMessage *msg = dynamic_cast<cube__CMessage *>(robjs->__ptr[i]);
		msg->print();
	}

	delete (*pobjs)[0];
	delete (*pobjs)[1];
	delete (*pobjs)[2];
	delete pobjs;


	cout << "----------- check the current instances ----------" << endl;

	pobjs = NULL;
	struct cube__invokeResponse res2;

	// get the active instances
	cube__CService *null_service = NULL;
	if(proxy.invoke(null_service, pobjs, res2)!=SOAP_OK) {
		soap_print_fault(proxy.soap(), stderr);

		delete (*pobjs)[0];
		delete (*pobjs)[1];
		delete (*pobjs)[2];
		delete pobjs;

		return -1;
	}

	cout << "active services = " << ((CObjectArray *)res2.out)->__size << endl;

	CObjectArray *r2objs = dynamic_cast<CObjectArray *>(res2.out);

	for(int i=0;i<r2objs->__size;i++) {
		cube__CKeyValue *kv = dynamic_cast<cube__CKeyValue *>(r2objs->__ptr[i]);
		cout << "+ " << kv->getKey() << "(" << kv->getValue() << ")" << endl;
	}

	if(pobjs!=NULL) delete pobjs;

	cout << "------------------ finalize --------------------" << endl;
	proxy.finalize(&echo_service, nothing);
	cout << endl;

#ifdef INFINITE
}
#endif

        return 0;
}
